package utils

import (
	"errors"
	"fmt"
	"gozeroSingle/define"
	"time"

	"github.com/golang-jwt/jwt/v4"
)

/*
 +----------------------------------------------------------------------
 + Title        : token
 + Author       : huwl
 + Version      : 1.0.0
 + Initial-Time : 2018-01-06
 + Last-time    : 这个文件最后修改的时间 + 修改人的名称
 + Desc         : golang-jwt
 +----------------------------------------------------------------------
*/

var (
	ErrTokenInvalid = errors.New("token无效/错误")
)

/**
 * 生成token
 *
 * @param uint64 uid ----------------------------必传
 * @return string, error
 * @author huwl
 * @date 2025/10/31 14:33:31
 */
func GenerateToken(id uint64) (string, error) {
	if id <= 0 {
		return "", errors.New("Id不能为空")
	}

	currentTime := time.Now().Unix()
	claims := make(jwt.MapClaims)
	claims["exp"] = currentTime + int64(define.TokenExpireTime)
	claims["iat"] = currentTime
	claims["id"] = id
	token := jwt.New(jwt.SigningMethodHS256)
	token.Claims = claims
	return token.SignedString([]byte(define.TokenSecret))
}

/**
 * 解析token
 *
 * @param string token ---------------------------必传
 * @return int64, error
 * @author huwl
 * @date 2025/10/31 14:33:31
 */
func ParseToken(token string) (int64, error) {
	if token == "" {
		return 0, errors.New("token不能为空")
	}

	parseToken, err := jwt.Parse(token, func(t *jwt.Token) (interface{}, error) {
		if _, ok := t.Method.(*jwt.SigningMethodHMAC); !ok {
			return nil, fmt.Errorf("Unexpected signing method: %v", t.Header["alg"])
		}

		return []byte(define.TokenSecret), nil
	})
	if err != nil {
		if IsContainStr([]string{"signature is invalid"}, err.Error()) {
			return 0, errors.New("token无效")
		}
		if IsContainStr([]string{"Token is expired"}, err.Error()) {
			return 0, errors.New("token已过期")
		}

		return 0, err
	}

	claims, ok := parseToken.Claims.(jwt.MapClaims)
	if !ok {
		return 0, errors.New("token错误")
	}

	val := claims["id"].(float64)
	return int64(val), nil

	// if claims, ok := parseToken.Claims.(jwt.MapClaims); ok && parseToken.Valid {
	// 	val := claims["id"].(float64)
	// 	exp := int64(claims["exp"].(float64))
	// 	if exp <= time.Now().Unix() {
	// 		return 0, errors.New("token已过期")
	// 	}

	// 	return int64(val), nil
	// }

	// return 0, errors.New("token 错误")
}
